package cn.com.hhrcw.enterprise.web;

import cn.com.hhrcw.enterprise.params.OpEntryHistoryParams;
import cn.com.hhrcw.enterprise.params.OpJobParams;
import cn.com.hhrcw.enterprise.vo.CvResumeVO;
import cn.com.hhrcw.enterprise.vo.OpInterviewHistoryVO;
import cn.com.hhrcw.enterprise.vo.PiInfoVO;
import cn.com.hhrcw.enterprise.vo.SsUserInfoVO;
import cn.com.hhrcw.entity.*;
import cn.com.hhrcw.mapstruct.*;
import cn.com.hhrcw.service.*;
import cn.com.hhrcw.utils.NewsUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.vo.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 简历库
 *
 * @program: recruit-boot-parent
 * @author: JD
 * @create: 2020-11-05 17:26
 **/
@RequestMapping("/en")
@Slf4j
@RestController
public class EnPersonnelController {

    @Autowired
    private IOpJobService opJobService;

    @Autowired
    private IOpEntryHistoryService opEntryHistoryService;

    @Autowired
    private EnOpEntryHistoryConvert enOpEntryHistoryConvert;

    @Autowired
    private IOpDeliveryHistoryService deliveryHistoryService;

    @Autowired
    private IPiInfoService piInfoService;

    @Autowired
    private ICvUserEduInfoService eduInfoService;

    @Autowired
    private EnCvUserEduInfoConvert eduInfoConvert;

    @Autowired
    private EnPiInfoConvert enPiInfoConvert;

    @Autowired
    private ICvUserWorkInfoService workInfoService;

    @Autowired
    private EnCvUserWorkInfoConvert workInfoConvert;

    @Autowired
    private ICvWorkIntentionService workIntentionService;

    @Autowired
    private EnCvWorkIntentionConvert workIntentionConvert;

    @Autowired
    private NewsUtil newsUtil;

    @Autowired
    private IOpInterviewHistoryService interviewHistoryService;

    @Autowired
    private EnOpInterviewHistoryConvert interviewHistoryConvert;

    @Autowired
    private IEnContactsService enContactsService;

    @Autowired
    EnEnContactsConvert contactsConvert;

    @Autowired
    private IOpInterviewContactService contactService;

    @Autowired
    private ISysUserDepartService userDepartService;

    @Autowired
    private EnOpDeliveryHistoryConvert deliveryHistoryConvert;

    @Autowired
    private EnOpJobConvert opJobConvert;

    @Autowired
    IOpEntryHistoryService entryHistoryService;

    @Autowired
    ICvResumeService resumeService;

    @Autowired
    EnCvResumeConvert resumeConvert;

    @Autowired
    IOpShieldingService opShieldingService;

    /**
     * 简历库-候选人列表
     *
     * @param params
     * @return
     */
    @GetMapping("/candidateList")
    @AutoLog(logType = 2, ty = "visit", value = "候选人列表查询")
    public Result<Page<SsUserInfoVO>> candidateList(OpJobParams params) {
        Map<String, Object> queryMap = new HashMap<>(16);
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        SysUserDepart depart = userDepartService.lambdaQuery().eq(SysUserDepart::getUserId, loginUser.getId()).one();
        queryMap.put("companyId", depart.getDepId());
        queryMap.put("sysFrom", params.getSysFrom());
        queryMap.put("bsType", params.getBsType());
        queryMap.put("state", null);
        int five = 5;
        if (params.getState() != null) {
            if (params.getState() == 0) {
                queryMap.put("state", new Integer[]{0, 1});
            } else if (params.getState() == five) {
                queryMap.put("state", new Integer[]{5, 9});
            } else {
                queryMap.put("state", new Integer[]{params.getState()});
            }
        }
        queryMap.put("jobName", params.getJobName());
        queryMap.put("name", params.getUserName());
        //            应聘时间范围 0 近三个月 1近半年
        queryMap.put("createTimeBegin", null);
        queryMap.put("createTimeEnd", null);
        Date now = new Date();
        if (params.getTimeState() != null && params.getTimeState() == 0) {
            queryMap.put("createTimeBegin", cn.hutool.core.date.DateUtil.offsetMonth(now, -3));
        } else if (params.getTimeState() != null && params.getTimeState() == 1) {
            queryMap.put("createTimeBegin", cn.hutool.core.date.DateUtil.offsetMonth(now, -6));
        }
        queryMap.put("createTimeEnd", now);

        if (params.getMinExperience() != null && params.getMaxExperience() != null) {
            if (params.getMinExperience() == 0 && params.getMaxExperience() == 0) {
                queryMap.put("jobTimeBegin", null);
                queryMap.put("jobTimeEnd", null);
            } else {
                String start = cn.com.hhrcw.utils.DateUtil.getYearFirst(params.getMaxExperience());
                String end = cn.com.hhrcw.utils.DateUtil.getYearLast(params.getMinExperience());
                queryMap.put("jobTimeBegin", start);
                queryMap.put("jobTimeEnd", end);
            }
        }
        List<OpShielding> shieldingList = opShieldingService.lambdaQuery().eq(OpShielding::getComId, depart.getDepId()).eq(OpShielding::getDelFlag, false).list();
        queryMap.put("filter",shieldingList.stream().map(OpShielding::getUserId).toArray());
        IPage<OpDeliveryHistory> page = deliveryHistoryService.resumeDeliveryList(params.page(), queryMap);
        return Result.success((Page<SsUserInfoVO>) pageConvert(page));
    }

    private IPage<SsUserInfoVO> pageConvert(IPage<OpDeliveryHistory> page) {
        return page.convert(e -> {
            SsUserInfoVO vo = new SsUserInfoVO();
            OpJob opJob = this.opJobService.getById(e.getJobId());
            PiInfo piInfo = this.piInfoService.lambdaQuery().eq(PiInfo::getUserId, e.getUserId()).one();
            //教育经历
            List<CvUserEduInfo> eduInfos = this.eduInfoService.lambdaQuery().eq(CvUserEduInfo::getResumeId, e.getResumeId()).eq(CvUserEduInfo::getUserId, e.getUserId()).list();
            //期望
            List<CvWorkIntention> workIntentions = this.workIntentionService.lambdaQuery().eq(CvWorkIntention::getResumeId, e.getResumeId()).list();
            //工作经历
            List<CvUserWorkInfo> userWorkInfos = this.workInfoService.lambdaQuery().eq(CvUserWorkInfo::getResumeId, e.getResumeId()).eq(CvUserWorkInfo::getUserId, e.getUserId()).list();
            //面试信息
            List<OpInterviewHistory> list = interviewHistoryService.lambdaQuery().eq(OpInterviewHistory::getDelFlag, false).eq(OpInterviewHistory::getJobId, e.getJobId()).eq(OpInterviewHistory::getUserId, e.getUserId()).orderByDesc(OpInterviewHistory::getCreateTime).list();
            List<OpInterviewHistoryVO> historyvos = this.interviewHistoryConvert.toVO(list);
            if (CollectionUtils.isNotEmpty(historyvos)) {
                for (OpInterviewHistoryVO interviewHistoryVO : historyvos) {
                    if (interviewHistoryVO.getTime() != null) {
                        //面试时间是已过 true 是 false 否
                        interviewHistoryVO.setTimeFlag(System.currentTimeMillis() > interviewHistoryVO.getTime().getTime());
                    }
                    EnContacts enContacts = enContactsService.getById(interviewHistoryVO.getContactId());
                    interviewHistoryVO.setContact(this.contactsConvert.toVO(enContacts));
                    List<OpInterviewContact> contact = contactService.lambdaQuery().eq(OpInterviewContact::getDelFlag, false).eq(OpInterviewContact::getViewId, interviewHistoryVO.getId()).list();
                    if (!org.springframework.util.CollectionUtils.isEmpty(contact)) {
                        List<PiInfo> contacts = contact.stream().map(el -> piInfoService.lambdaQuery().eq(PiInfo::getUserId, el.getContactId()).one()).filter(Objects::nonNull).collect(Collectors.toList());
                        interviewHistoryVO.setConInfo(enPiInfoConvert.toVO(contacts));
                    }
                }
            }
            //简历信息
            CvResume resume = resumeService.getById(e.getResumeId());
            List<CvResumeVO> resumevos = new ArrayList<>();
            resumevos.add(resumeConvert.toVO(resume));
            vo.setCvResumeList(resumevos);
            //入职记录
            OpEntryHistory entryHistory = entryHistoryService.lambdaQuery().eq(OpEntryHistory::getDelFlag, false).eq(OpEntryHistory::getUserId, e.getUserId()).eq(OpEntryHistory::getJobId, e.getJobId()).one();
            vo.setOpInterviewHistory(historyvos);
            vo.setEntryHistory(this.enOpEntryHistoryConvert.toVO(entryHistory));
            if (entryHistory != null) {
                EnContacts enContacts = enContactsService.getById(entryHistory.getContactId());
                vo.getEntryHistory().setContact(contactsConvert.toVO(enContacts));
            }
            vo.setDataId(e.getId());
            PiInfoVO piInfoVO = this.enPiInfoConvert.toVO(piInfo);
            piInfoVO.setWorkYears(piInfo.getWorkYears());
            vo.setUserInfo(piInfoVO);
            vo.setWorkIntention(this.workIntentionConvert.toVO(workIntentions));
            vo.setWorkInfo(this.workInfoConvert.toVO(userWorkInfos));
            vo.setEduInfo(this.eduInfoConvert.toVO(eduInfos));
            vo.setJobTime(e.getCreateTime());
            vo.setJobName(opJob.getJobName());
            vo.setJobId(opJob.getId());
            vo.setJob(this.opJobConvert.toVO(opJob));
            vo.setComId(e.getCompanyId());
            vo.setDeliveryHistory(this.deliveryHistoryConvert.toVO(e));
            vo.setReId(e.getResumeId());
            vo.setSysFrom(opJob.getSysFrom());
            vo.setBsId(opJob.getBsId());
            vo.setBsType(opJob.getBsType());
            return vo;
        });
    }
    /**
     * 列表查询条件构造
     *
     * @param query
     * @param params
     */
    private Boolean createCandidateListWrapper(QueryWrapper<OpDeliveryHistory> query, OpJobParams params, LoginUser sysUser) {
        SysUserDepart userDepart = userDepartService.lambdaQuery().eq(SysUserDepart::getUserId, sysUser.getId()).one();
        query.eq("op_delivery_history.company_id", userDepart.getDepId());
        boolean conFlag = StringUtils.isNotBlank(params.getConName()) && params.getState() == 5;
        if (conFlag) {
            List<EnContacts> contacts = enContactsService.lambdaQuery().like(EnContacts::getUserName, params.getConName()).eq(EnContacts::getDelFlag, false).list();
            if (CollectionUtils.isEmpty(contacts)) {
                return false;
            }
            List<String> conIds = new ArrayList<>();
            contacts.forEach(enContacts -> {
                conIds.add(enContacts.getId());
            });
            List<OpEntryHistory> histories = opEntryHistoryService.lambdaQuery().in(OpEntryHistory::getContactId, conIds).eq(OpEntryHistory::getDelFlag, false).select(OpEntryHistory::getJobId, OpEntryHistory::getUserId).list();
            if (CollectionUtils.isEmpty(histories)) {
                return false;
            }
            query.and(queryIn -> {
                histories.forEach(e -> {
                    queryIn.or(queryInIn -> queryInIn.eq("op_delivery_history.job_id", e.getJobId()).eq("op_delivery_history.user_id", e.getUserId()));
                });
                return queryIn;
            });
        }
        //屏蔽
        List<OpShielding> shieldingList = opShieldingService.lambdaQuery().eq(OpShielding::getComId, userDepart.getDepId()).eq(OpShielding::getDelFlag, false).list();
        if (CollectionUtils.isNotEmpty(shieldingList)) {
            query.notIn("op_delivery_history.user_id", shieldingList.stream().map(OpShielding::getUserId).toArray());
        }
        //0 未阅读  1 已阅读 2 不合适 3通过筛选4 面试 5已发offer(已录用) 6 已入职 7 被系统过滤 8未入职9反馈面试结果(通过)10反馈面试结果(不通过)
        boolean flag = params.getState() == 5;
        if (params.getState() == 0) {
            query.in("op_delivery_history.state", 0, 1);
        } else if (flag) {
            query.in("op_delivery_history.state", 5, 9);
        } else {
            query.in("op_delivery_history.state", params.getState());
        }
        boolean enConFlag = StringUtils.isNotBlank(params.getConName()) && params.getState() == 4;
        if (enConFlag) {
            List<EnContacts> contacts = enContactsService.lambdaQuery().like(EnContacts::getUserName, params.getConName()).eq(EnContacts::getDelFlag, false).list();
            if (CollectionUtils.isEmpty(contacts)) {
                return false;
            }
            List<String> conIds = new ArrayList<>();
            contacts.forEach(enContacts -> {
                conIds.add(enContacts.getId());
            });
            List<OpInterviewHistory> histories = interviewHistoryService.lambdaQuery().in(OpInterviewHistory::getContactId, conIds).eq(OpInterviewHistory::getDelFlag, false).select(OpInterviewHistory::getJobId, OpInterviewHistory::getUserId).list();
            if (CollectionUtils.isEmpty(histories)) {
                return false;
            }
            query.and(queryIn -> {
                histories.forEach(e -> {
                    queryIn.or(queryInIn -> queryInIn.eq("op_delivery_history.job_id", e.getJobId()).eq("op_delivery_history.user_id", e.getUserId()));
                });
                return queryIn;
            });
        }
        //职位发布源
        if (params.getSource() != null) {
            switch (params.getSource()) {
                case 1:
                    query.eq("op_job.sys_from", 2).eq("op_job.bs_type", 0);
                    break;
                case 2:
                    query.eq("op_job.sys_from", 2).eq("op_job.bs_type", 1);
                    break;
                case 3:
                    query.eq("op_job.sys_from", 1);
                    break;
                default:
                    break;
            }
        }
        return true;
    }

    /**
     * 录用
     *
     * @param params 请求参数
     * @return
     */
    @PostMapping(value = "/addEntry")
    @AutoLog(logType = 2, ty = "insert", value = "入职邀请添加")
    @ApiOperation(value = "添加", notes = "添加")
    @RequiresPermissions("opEntryHistory:add")
    public Result<?> add(@RequestBody @Valid OpEntryHistoryParams params) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        OpEntryHistory opEntryHistory = enOpEntryHistoryConvert.toEntity(params);
        opEntryHistory.setCreateBy(sysUser.getId());
        opEntryHistory.setCreateTime(DateUtil.date());
        opEntryHistory.setDelFlag(false);
        boolean saved = opEntryHistoryService.save(opEntryHistory);
        newsUtil.creatNews(params.getUserId(), sysUser.getId(), 0, 1, opEntryHistory.getId(), "2");
        return saved ? Result.ok() : Result.error("添加失败");
    }

}
